﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using iNet.IO;
using iNet.Tasks;

namespace iNet.Media.Video
{
	/// <summary>
	/// 通用影片解碼工作。
	/// </summary>
	public class GenericVideoDecodeTask : VideoDecodeTask
	{
		#region 欄位
		IMediaFormat _DecodingFormat;
		#endregion
		#region 建構子
		/// <summary>
		/// 初始化新的 GenericVideoDecodeTask 執行個體。
		/// </summary>
		public GenericVideoDecodeTask()
			: base(null, null, MediaDecodeRequests.All, VideoDecodeRequests.All)
		{ }
		/// <summary>
		/// 初始化新的 GenericVideoDecodeTask 執行個體。
		/// </summary>
		/// <param name="source">影片儲存來源。</param>
		public GenericVideoDecodeTask(MediaStorage source)
			: base(null, source, MediaDecodeRequests.All, VideoDecodeRequests.All)
		{ }
		/// <summary>
		/// 初始化新的 GenericVideoDecodeTask 執行個體。
		/// </summary>
		/// <param name="source">影片儲存來源。</param>
		/// <param name="mediaDecodeReqs">媒體解碼請求。</param>
		/// <param name="videoDecodeReqs">影片解碼請求。</param>
		public GenericVideoDecodeTask(MediaStorage source, MediaDecodeRequests mediaDecodeReqs, VideoDecodeRequests videoDecodeReqs)
			: base(null, source, mediaDecodeReqs, videoDecodeReqs)
		{ }
		#endregion
		#region Decode
		/// <summary>
		/// 解碼影片。
		/// </summary>
		/// <param name="version">目前的工作版本。</param>
		/// <param name="source">影片儲存來源。</param>
		/// <param name="mediaDecodeReqs">媒體解碼請求。</param>
		/// <param name="videoDecodeReqs">影片解碼請求。</param>
		/// <returns>True 表示解碼成功，False 表示失敗。</returns>
		protected override bool Decode(TaskVersion version, MediaStorage source, MediaDecodeRequests mediaDecodeReqs, VideoDecodeRequests videoDecodeReqs)
		{
			//建立解碼工作
			Stream stream;
			if (!this.GetMediaStorageStream(version, source, MediaStorageStreamFlags.Readable, 50, out stream))
				throw new MediaDecodeFailedException(MediaDecodeFailedReason.CannotAccessStream);
			VideoDecodeTask decodeTask;
			try
			{
				decodeTask = VideoCodecs.CreateDecodeTask(stream);
			}
			finally
			{
				this.ReleaseMediaStorageStream(version, source, stream);
			}
			if (decodeTask == null)
				return false;

			//取得解碼格式
			this.WriteValue<IMediaFormat>(version, ref _DecodingFormat, decodeTask.DecodingFormat);

			//解碼影像
			double? baseProgress = this.Progress;
			if (baseProgress != null)
			{
				double progressRange = ((100 - baseProgress.Value) / 100);
				decodeTask.ProgressChanged += (sender, e) =>
				{
					this.ReportProgress(version, baseProgress + (e.Progress * progressRange));
				};
			}
			decodeTask.Source = source;
			switch (this.ExecuteChildDecodeTask(version, decodeTask))
			{
				case TaskState.Executed:
					this.ReportProgress(version, 100);
					break;
				case TaskState.Canceled:
					return true;
				default:
					return false;
			}

			//完成
			return true;
		}
		#endregion
		#region DecodingFormat
		/// <summary>
		/// 取得影片解碼格式，Null (Visual Basic 為 Nothing) 表示尚未確認影片格式。
		/// </summary>
		public override IMediaFormat DecodingFormat
		{
			get
			{
				return _DecodingFormat;
			}
		}
		#endregion
		#region ResetOverride
		/// <summary>
		/// 重設工作狀態。
		/// </summary>
		protected override void ResetOverride()
		{
			_DecodingFormat = null;
			base.ResetOverride();
		}
		#endregion
	}
}
